Ant Design v4

记录项目开发过程中遇到的一些问题(antd 4.x)

官网镜像地址

https://ant-design.gitee.io/index-cn (来自issues 25661

default.less

https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less

Form

根据某个表单项的值渲染其他表单项

shouldUpdate

shouldUpdate: boolean | (prevValue, curValue) => boolean

1
2
3
4
5
6
7
8
9
10
<Form.Item noStyle shouldUpdate>
{({getFieldValue}) => {
// 通过getFieldValue获取所需的字段值
return (
<Form.Item name="other">
<Input/>
</Form.Item>
)
}}
</Form.Item>

一个表单项中有多个控件

复杂一点的控件

提交失败时自动滚动到指定字段

自定义表单控件 scrollToFirstError 和 scrollToField 失效?

  1. scrollToFirstError

提交失败自动滚动到第一个错误字段。

注意:必须使用表单submit提交才会触发。

  1. scrollToField

如果不使用表单submit提交,使用scrollToField滚动到对应字段位置:

1
scrollToField(name: NamePath, options: ScrollOptions)

ScrollOptions

1
2
3
4
5
6
7
8
9
10
const submit = async () => {
try {
const values = await form.validateFields();
} catch (errorInfo) {
// 滚动到第一个错误字段
form.scrollToField(errorInfo.errorFields[0].name, {
block: 'center',
})
}
}

嵌套结构校验

校验嵌套数据结构中的某几个项:

1
2
3
4
5
6
<FormItem name={['app', 'name' ]}>
<Input />
</FormItem>
<FormItem name={['app', 'desc' ]}>
<Input />
</FormItem>
1
2
// 只校验app.name
form.validateFields([['app', 'name' ]])

Form.List的局部校验

https://juejin.cn/post/6844904176770613261

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 单行验证, index代表的是第几行数据
form.validateFields([
['users', index, 'firstName'],
['users', index, 'lastName']
]).then(values => {
console.log(values.users[index].firstName, values.users[index].lastName)
});

// 整个users验证需要把每行的field name传进去,暂未找到别的解决方案
form.validateFields([
['users', 0, 'firstName'],
['users', 0, 'lastName'],
['users', 1, 'firstName'],
['users', 1, 'lastName']
])

关闭Modal销毁form中的数据

4.5.0之后,可以给Form加上preserve={false}属性来清除跟随Modal 销毁的字段数据:https://codesandbox.io/s/mystifying-sound-lkin8

Select

如果发现下拉菜单跟随页面滚动,或者需要在其他弹层中触发 Select,请尝试使用getPopupContainer={triggerNode => triggerNode.parentElement}将下拉弹层渲染节点固定在触发器的父元素中。

自定义回填内容

optionLabelProp="name"

1
2
3
<Select optionLabelProp="name">
<Option key="..." name={opt.name} value="..."} />
</Select>

自定义搜索筛选filterOption

利用option.keyoption.title

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Select showSearch filterOption={(input, option) => {
const inputSearch = input.toLowerCase();
return option.key.toLowerCase().indexOf(inputSearch) >= 0 || option.title.toLowerCase().indexOf(inputSearch) >= 0;
}}>
{countries.map((country) => {
const { abbreviation, emoji, englishName } = country;
const value = valueWidthName ? `${abbreviation},${englishName}` : abbreviation;
return (
<Option key={value} title={englishName} value={value}>
<div className={classNames(style.option, optionClassName)}>
<Twemoji className={classNames(style.emoji, emojiClassName)}>{emoji}</Twemoji>
<span className={style.name}>{englishName}</span>
</div>
</Option>
);
})}
</Select>

滚动加载

onPopupScroll: 下拉列表滚动时的回调

1
2
3
4
5
6
7
8
9
const handlePopupScroll = (e) => {
const {target} = e
if (target.scrollTop + target.offsetHeight === target.scrollHeight) {
if (loading) {
return
}
// ...
}
}

Tree

虚拟滚动

默认virtual: true开启虚拟滚动,通过添加height属性激活。如果需要支持横向滚动,应该关闭虚拟滚动,因为虚拟滚动不会渲染所有节点,无法自动拓转横向宽度(虚拟滚动的限制)。

onSelect获取key

1
2
3
4
const onSelect = (selectedKeys, e) => {
const key = e.node.key
// ...
}

Affix

页面顶部导航栏用<Affix offsetTop={0}>包裹,滚动时会抖动。

解决方法:<Affix offsetTop={0.1}>

Drawer

监听滚动事件

Drawer滚动事件在ant-drawer-body节点上,可以通过修改css,转移滚动对象,使ant-drawer-body不滚动。

网页全屏下Modal不显示问题

使用getContainer

1
2
3
4
5
<Modal
getContainer={() => dom} // <----
>
// ...
</Modal>

Table

超过宽度省略

暂不支持和排序筛选一起使用。
设置为 true 或 { showTitle?: boolean } 时,表格布局将变成 tableLayout=”fixed”

1
2
3
4
5
6
columns = [
{
// ...
ellipsis: true,
}
]

flex布局下Table宽度溢出问题

https://github.com/ant-design/ant-design/issues/28158#issuecomment-737648133

设置flex元素:

1
2
3
4
.flex {
flex: auto;
min-width: 0;
}

Upload

beforeUpload

阻止不符合要求的文件上传return Upload.LIST_IGNORE

1
2
3
4
5
6
7
function beforeUpload(file) {
if (file.size > 1024 * 1024 * MAX_FILES_SIZE) {
message.error('error');
return Upload.LIST_IGNORE;
}
return true;
}